iT邦幫忙

2024 iThome 鐵人賽

DAY 29
0
JavaScript

歡迎參加我的原生JS畢業典禮系列 第 29

【Day28】.NET Core MVC & Vue—Bootstrap套件也能v-for!

  • 分享至 

  • xImage
  •  

參賽進入最尾聲了,剩下最後一個實戰任務!將會用我之前透過.net MVC開發的訂房網站為基礎進行;昨天我們已經連上了本機資料庫,並測試成功把資料丟到View,接下來就是將資料配合排版呈現!

這系列兩大重點:

  1. 實際操作本機資料庫
  2. 當Vue.js加入.NET Core MVC專案後,是如何改善透過jQuery處理前端畫面的程式碼

熱門房型

在訂房首頁中,我們會看到一些熱門房型的呈現:
https://ithelp.ithome.com.tw/upload/images/20241013/20169356Gb5byx9zOU.png
▲這些資料我們讓HomeController在開啟首頁的同時一併交付給View

回到HomeController的Index()

  • 修改LinQ語法:昨天我們只是隨意撈了一個欄位進行測試,現在我們撈取三筆資料作為首頁顯示
//HomeController
   public IActionResult Index()
   {
       var result = from room in ud_RoomContext.ut_BS001.Take(3)
                    select new ut_BS001
                    {
                        BS01_01 = room.BS01_01,
                        BS01_02 = room.BS01_02,
                        BS01_03 = room.BS01_03,
                        BS01_04 = room.BS01_04,
                        BS01_07 = (room.BS01_07 == null? "roomsetting.png" : room.BS01_07),
                        BS01_08 = room.BS01_08,
                        BS01_09 = room.BS01_09,
                        BS01_10 = (room.BS01_01 == 1 ? "單人房":
                        room.BS01_01 == 2 ? "雙人房":
                        room.BS01_01 == 3 ? "家庭房": ""
                        ),
                        BS01_11 = room.BS01_11 
                    };

       return View(result);
   }
  1. function的回傳值改為IActionResult
  2. .Take(3)可以讓我們在該資料表取用相對應的筆數
  3. 在select中判斷資料的值並進行替換

相當於SQL的語法:

SELECT TOP(3) [u].[BS01_01], [u].[BS01_02], [u].[BS01_03], [u].[BS01_04], CASE
    WHEN [u].[BS01_07] IS NULL THEN N'roomsetting.png'
    ELSE [u].[BS01_07]
END AS [BS01_07], [u].[BS01_08], [u].[BS01_09], CASE
    WHEN [u].[BS01_01] = 1 THEN N'單人房'
    WHEN [u].[BS01_01] = 2 THEN N'雙人房'
    WHEN [u].[BS01_01] = 3 THEN N'家庭房'
    ELSE N''
END AS [BS01_10], [u].[BS01_11]

回到Index.cshtml

前端要去接這包資料:使用IEnumerable泛型別列舉

//Index.cshtml
@model IEnumerable<ut_BS001>

因為資料是從DB過來的,這裡的資料處理透過Razor就可以了

//Index.cshtml
<div id="hitRoom">
    <div>
        @foreach (var room in Model)
        {
            <div class="col-3 roomInfo">
                <span class="span_roomInfo">
                    <text>@room.BS01_10</text>
                    <img src="./img/@room.BS01_07">
                </span>
                <text>@room.BS01_03</text>
                <span><text>@room.BS01_04</text><text> ∕ 晚</text></span>
            </div>
        }
    </div>
</div>

圖片輪播器

在網站上方,通常會出現商品展示的圖片輪播器,會有一些圖片和控制的按鈕:
https://ithelp.ithome.com.tw/upload/images/20241013/20169356NSqNfSr21t.png
▲這裡我使用Bootstarp裡面的輪播器套件,並做點修改

因為圖片已經存在在專案中了,這裡我把它們包成一個響應式的ref資料,讓Vue來幫我處理:

@section Scripts{
 <script type="module">
    import { ref, createApp } from './vue/dist/vue.esm-browser.prod.js';
    createApp({
        setup(){
            const nowImg=ref(1);
            const carouselImg = ref([
                                       {
                                           id:1,
                                           src:"./img/banner01.jpg",
                                       },
                                       {
                                           id:2,
                                           src:"./img/banner02.jpg",
                                       },
                                       {
                                           id:3,
                                           src:"./img/banner03.jpg",
                                       }
                                   ]);
                                   return {carouselImg,nowImg};
                }
            }).mount("#carouselExampleIndicators");
    </script>  
}
  • nowImg:指定當前圖片
  • carouselImg:要進入輪播的物件檔
//這個區塊對應輪播器下方的按鈕,以v-for方式渲染
    <div class="carousel-indicators">
        <button v-for="img in carouselImg" v-bind:key="img.id" type="button" data-bs-target="#carouselExampleIndicators" v-bind:data-bs-slide-to="img.id-1" v-bind:class="{'active' : nowImg === img.id}" aria-current="true"></button>
    </div>
    
//這個區塊對應輪播器中的圖片,以v-for方式渲染
    <div class="carousel-inner">
        <div class="carousel-item" v-bind:class="{'active' : nowImg === img.id}" v-for="img in carouselImg" v-bind:key="img.id">
            <img v-bind:src="img.src" style="margin-top:-200px" class="d-block w-100">
        </div>
    </div>

這樣看起來可能無感,但如果在Vue沒有幫我處理前的html會長這樣,就是每個重複的DOM都要一直重寫:

  <div class="carousel-indicators">
            <button type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide-to="0" class="active" aria-current="true" aria-label="Slide 1"></button>
            <button type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide-to="1" aria-label="Slide 2"></button>
            <button type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide-to="2" aria-label="Slide 3"></button>
        </div>
        <div class="carousel-inner">
            <div class="carousel-item active">
                <img src="~/Image/banner01.jpg" style="margin-top:-200px" class="d-block w-100">
            </div>
            <div class="carousel-item">
                <img src="~/Image/banner02.jpg" style="margin-top:-180px" class="d-block w-100">
            </div>
            <div class="carousel-item">
                <img src="~/Image/banner03.jpg" style="margin-top:-300px" class="d-block w-100">
            </div>
        </div>

看起來應該是有簡單俐落了一些吧!

小結

之前在Vue專案下練習太仰賴SFC的環境了,現在還是有點不熟悉引入CDN,不過再多寫幾次應該就會習慣了(吧)?


參考資料
IEnumerable 介面
组合式 API:setup()


上一篇
【Day27】.NET Core MVC & Vue—DI注入連線本機資料庫
下一篇
【Day29】.NET Core MVC & Vue—讓Axios幫我拿資料
系列文
歡迎參加我的原生JS畢業典禮31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言